#include "opengauss/libpq-fe.h"
#include <string>
#include <iostream>

// 检查连接状态和执行结果
void checkResult(PGresult *res, PGconn *conn)
{
    if (PQresultStatus(res) != PGRES_COMMAND_OK)
    {
        std::string errorMessage = "执行 SQL 语句出错: " + std::string(PQerrorMessage(conn));
        PQclear(res);
        throw std::runtime_error(errorMessage);
    }
    PQclear(res);
}

// 单独的创建PGconn连接的函数
PGconn *createPGConnection(const std::string &connectionInfo)
{
    PGconn *conn = PQconnectdb(connectionInfo.c_str());
    if (PQstatus(conn) != CONNECTION_OK)
    {
        std::cerr << "连接数据库出错: " << PQerrorMessage(conn) << std::endl;
        PQfinish(conn);
        return nullptr;
    }
    return conn;
}

int CreateTable(PGconn *conn)
{
    // 准备创建表的 SQL 语句
    const char *sql = "CREATE TABLE IF NOT EXISTS my_table ("
                      "id SERIAL PRIMARY KEY,"
                      "name VARCHAR(100),"
                      "age INTEGER"
                      ");";

    // 执行 SQL 语句
    PGresult *res = PQexec(conn, sql);
    if (PQresultStatus(res) != PGRES_COMMAND_OK)
    {
        fprintf(stderr, "Failed to create table: %s", PQerrorMessage(conn));
        PQclear(res);
        return EXIT_FAILURE;
    }

    printf("Table created successfully.\n");

    // 清理结果
    PQclear(res);
    return EXIT_SUCCESS;
}

int InsertTable(PGconn *conn, const char *sql)
{
    // 开始事务
    PGresult *res = PQexec(conn, "BEGIN");
    try
    {
        checkResult(res, conn);

        // 执行一些 SQL 操作
        res = PQexec(conn, sql);
        checkResult(res, conn);

        // 其他 SQL 操作...

        // 提交事务
        res = PQexec(conn, "COMMIT");
        checkResult(res, conn);
        std::cout << "事务提交成功。" << std::endl;
    }
    catch (const std::exception &e)
    {
        // 回滚事务
        res = PQexec(conn, "ROLLBACK");
        try
        {
            checkResult(res, conn);
        }
        catch (...)
        {
            std::cerr << "回滚事务时出错。" << std::endl;
        }
        std::cout << "事务已回滚。错误信息: " << e.what() << std::endl;
        return -1;
    }
    return 0;
}

